#include "widget.h"
#include "ui_widget.h"

#define WIDTH 1200
#define HEIGHT 800
#define LENGTH 400
#define TOTAL_STATION 9
#define DISTANCE 2


QVector<QString>head;
QVector<QVector<int>> array; //输出的数组
QVector<QVector<int>> waittime; //等待时间
int curtime; //计时器
QQueue<node> Q;
bus Bus;
QString s;
int x_1 = 100;
int y_1 = 180;
int x_2 = x_1 + LENGTH;
int y_2 = y_1 + LENGTH;
int distance = LENGTH * 4 / (TOTAL_STATION * DISTANCE);
int bus_x = x_1;
int bus_y = y_1;

//构造函数
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->bus->installEventFilter(this);
    setFixedSize(1200,800);
    //创建数组，并完成初始化
    array.resize(3);
    for(int j=0;j<array.size();j++)
    {
        array[j].resize(TOTAL_STATION+2);
    }
    waittime.resize(3);
    for(int j=0;j<waittime.size();j++)
    {
        waittime[j].resize(TOTAL_STATION);
    }
     //设置当前时间
    curtime=0;
    //label中填充图片
    QImage Image;
    Image.load(":/img/img/bus.png");
    QPixmap pixmap = QPixmap::fromImage(Image);
    int with = ui->label->width();
    int height = ui->label->height();
    QPixmap fitpixmap = pixmap.scaled(with, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);  // 按比例缩放
    ui->label->setPixmap(fitpixmap);
    ui->label->move(QPoint(bus_x,bus_y));
    ui->state->setText("等待请求中...");
    QPixmap p;
    p.load(":/img/img/flower.png");
    p.scaled(ui->icon->size(), Qt::KeepAspectRatio);
    ui->icon->setScaledContents(true);
    ui->icon->setPixmap(p);


    //链接槽函数和信号（点击按钮将文本框中输入的内容取得）
    connect(ui->TButton,&QPushButton::clicked,this,&Widget::TchangArr);
    connect(ui->CButton,&QPushButton::clicked,this,&Widget::CchangArr);
    connect(ui->UButton,&QPushButton::clicked,this,&Widget::UchangArr);
    //设置定时器
    startTimer(1500);
}

//下面两个函数用于在左侧的label中绘制矩形，在画边界的时候比较费脑子
bool Widget::eventFilter(QObject *watched, QEvent *event) {
    if (watched == ui->bus && event->type() == QEvent::Paint) {
        paintbus();
    }
    return QWidget::eventFilter(watched, event);
}

void Widget::paintbus() {

    QPainter painter(ui->bus);

    //绘制矩形
    QPen pen(QColor(200, 200, 200));
    pen.setWidth(7);
    painter.setPen(pen);
    int margin_left=100;
    int margin_top=(HEIGHT-LENGTH)/2;
    QRectF rectangle(margin_left,margin_top, LENGTH, LENGTH);  //坐标，宽高
    painter.drawRect(rectangle);
    //绘制上面的点
    int x=margin_left;
    int y=margin_top;
    int flag=1;
    for(int i=0;i<TOTAL_STATION * DISTANCE; i++)
    {
        if (i % DISTANCE)
        {
            painter.setPen(QColor(Qt::black));
            painter.setBrush(QBrush(Qt::black));
            painter.drawEllipse(x-4,y-4,7,7);
        }
        else {
            painter.setPen(QColor(Qt::red));
            painter.setBrush(QBrush(Qt::red));
            painter.drawEllipse(x-4,y-4,13,13);
        }

        if(flag==1&&LENGTH-(x-margin_left)<=distance){
            y+=distance-(LENGTH-(x-margin_left));
            x=margin_left+LENGTH;
            flag=2;
            
        }
        else if(flag==1&&LENGTH-(x-margin_left)>distance){
            x+=distance;

        }
        else if(flag==2&&LENGTH-(y-margin_top)<=distance)
        {
            x-=distance-(LENGTH-(y-margin_top));
            y=margin_top+LENGTH;
            flag=3;
        }
        else if(flag==2&&LENGTH-(y-margin_top)>distance)
        {
            y+=distance;
        }
        else if(flag==3&&(x-margin_left)<=distance)
        {
            y-=distance-(x-margin_left);
            x=margin_left;
            flag=4;
        }
        else if(flag==3&&(x-margin_left)>distance)
        {
            x-=distance;
        }
        else if(flag==4&&(y-margin_top)<=distance){
            y=margin_top;
            x+=distance-((y-margin_top));
            flag=1;
        }
        else if(flag==4&&(y-margin_top)>distance){
            y-=distance;
        }
    }
}



//点击按钮后收到数据并改变对应二进制数组
void Widget::TchangArr(){
    QString temp=ui->Tedit->text();
    int station_num=temp.toInt();
    if ( array[0][station_num] == 1) //请求重复，该请求丢弃
    {
        ui->Tedit->clear();
        return ;
    }
    else{
        node temp={station_num,0,curtime};
        if (Q.isEmpty())
        {

            Q.enqueue(temp);
            qDebug()<<"插入target成功";
            node start = Q.head();
            ShortDirection(start.servise_position);
        }
        else
        {
            //如果队列不为空
            Q.enqueue(temp);
            qDebug()<<"插入target成功";
        }
        //改变array[0]数组
        array[0][station_num]=1;
        update();
    }

    ui->Tedit->clear();
}
void Widget::CchangArr(){
    QString temp=ui->Cedit->text();
    int station_num=temp.toInt();
    if ( array[1][station_num] == 1) //请求重复，该请求丢弃
    {
        ui->Tedit->clear();
        return ;
    }
    else{
        node temp = {station_num, 1, curtime};
        if (Q.isEmpty())
        {
            Q.enqueue(temp);
            node start = Q.head();
            ShortDirection(start.servise_position);
        }
        else
        { //如果队列不为空
            Q.enqueue(temp);
        }
        //改变array[0]数组
        array[1][station_num]=1;
        update();
    }
    ui->Cedit->clear();
}
void Widget::UchangArr(){
    QString temp=ui->Uedit->text();
    int station_num=temp.toInt();
    if ( array[2][station_num-1] == 1) //请求重复，该请求丢弃
    {
        ui->Tedit->clear();
        return ;
    }
    else{
        node temp = {station_num, 2, curtime};
        if (Q.isEmpty())
        {
            Q.enqueue(temp);
            node start = Q.head();
            ShortDirection(start.servise_position);
        }
        else
        { //如果队列不为空
            Q.enqueue(temp);
        }
        //改变array[0]数组
        array[2][station_num-1]=1;
        update();
    }
    ui->Uedit->clear();
}

//定时器
void Widget::timerEvent(QTimerEvent *)
{
    curtime++;
    update();

}
//更新时间数组，
void Widget::update(){
    for (int i = 0; i < TOTAL_STATION; i++)
    {
        if (array[0][i] == 1)
        {
            waittime[0][i]++;
        }
        if (array[1][i] == 1)
        {
            waittime[1][i]++;
        }
        if (array[2][i] == 1)
        {
            waittime[2][i]++;
        }
    }

    if (Q.isEmpty() == 1)
    {
        output();
        ui->state->setText("等待请求中...");
        return;
    }
    else
    {
        //如果队列不为空，获取队列的队头，判断其servise_direction
        node temp = Q.head();
        if (Bus.position % DISTANCE == 0 && (temp.servise_position) - 1 == Bus.position / DISTANCE)
        {
            ui->state->setText("到站了,停车等待");
            //如果到站
            if (temp.servise_direction == 1)
            {
                waittime[1][Bus.position / DISTANCE + 1] = 0;
                array[1][Bus.position / DISTANCE + 1] = 0;
            }
            else if (temp.servise_direction == 2)
            { //如果是逆时针的请求服务
                waittime[2][Bus.position / DISTANCE + 1] = 0;
                array[2][Bus.position / DISTANCE + 1] = 0;
            }
            else if (temp.servise_direction == 0)
            {
                //如果是target服务
                array[0][Bus.position / DISTANCE + 1] = 0;
                waittime[0][Bus.position / DISTANCE + 1] = 0;
            }
            Q.dequeue();
            if (!Q.isEmpty())
            {
                temp = Q.head();
                while (!Q.isEmpty() && Bus.position % DISTANCE == 0 &&
                       temp.servise_position - 1 == Bus.position / DISTANCE)
                {
                    ui->state->setText("到站了,停车等待");
                    if (temp.servise_direction == 1)
                    {
                        waittime[1][Bus.position / DISTANCE + 1] = 0;
                        array[1][Bus.position / DISTANCE + 1] = 0;
                    }
                    else if (temp.servise_direction == 2)
                    { //如果是逆时针的请求服务
                        waittime[2][Bus.position / DISTANCE + 1] = 0;
                        array[2][Bus.position / DISTANCE + 1] = 0;
                    }
                    else if (temp.servise_direction == 0)
                    {
                        //如果是target服务
                        array[0][Bus.position / DISTANCE + 1] = 0;
                        waittime[0][Bus.position / DISTANCE + 1] = 0;
                    }
                    Q.dequeue();
                    if (Q.isEmpty())
                    {
                        break;
                    }
                    else
                        temp = Q.head();
                }
            }

            output();
            //更改行驶方向
            if (Q.isEmpty())
            {
                return ;
            }
            node start = Q.head();
            ShortDirection(start.servise_position);
        }

        else //没到站，移动。输出
            //移动，该小车运动了，这里小车移动用到了QPropertyAnimation，在转角的地方用到了插值运动
        {
            ui->state->setText("车辆行驶中...");
            if (Bus.direction == 1)
            { //如果为顺时针
                if (Bus.position == DISTANCE * TOTAL_STATION - 1)
                { //到右边的边界
                    Bus.position = 0;
                }
                else
                    Bus.position++;
                if(bus_y==y_1){
                    if(x_2-bus_x>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x+=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else {
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        anim->setKeyValueAt(0.5,QPoint(x_2,y_1));
                        bus_y+=distance-(x_2-bus_x);
                        bus_x=x_2;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_x==x_2){
                    if(y_2-bus_y>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y+=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y=y_2;
                        bus_x-=distance-(y_2-bus_y);
                        anim->setKeyValueAt(0.5,QPoint(x_2,y_2));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_y==y_2){
                    if(bus_x-x_1>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x-=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y -= distance - (bus_x - x_1);
                        bus_x=x_1;
                        anim->setKeyValueAt(0.5,QPoint(x_1,y_2));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_x==x_1){
                    if(bus_y-y_1>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y-=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y=y_1;
                        bus_x+=distance-(bus_y-y_1);
                        anim->setKeyValueAt(0.5,QPoint(x_1,y_1));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }

            }
            else if (Bus.direction == 2)
            { //如果为逆时针
                if (Bus.position == 0)
                { //到左边的边界
                    Bus.position = DISTANCE * TOTAL_STATION - 1;
                }
                else
                    Bus.position--;
                if(bus_y==y_1){
                    if(bus_x-x_1>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x-=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else {
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        anim->setKeyValueAt(0.5,QPoint(x_1,y_1));
                        bus_y+=distance-(bus_x-x_1);
                        bus_x=x_1;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_x==x_1){
                    if(y_2-bus_y>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y+=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x+=distance-(y_2-bus_y);
                        bus_y=y_2;
                        anim->setKeyValueAt(0.5,QPoint(x_1,y_2));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_y==y_2){
                    if(x_2-bus_x>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x+=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y -= distance - (x_2-bus_x);
                        bus_x=x_2;
                        anim->setKeyValueAt(0.5,QPoint(x_2,y_2));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
                else if(bus_x==x_2){
                    if(bus_y-y_1>distance){
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_y-=distance;
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                    else{
                        QPropertyAnimation *anim= new QPropertyAnimation(ui->label, "pos" );
                        anim->setDuration(1000);
                        anim->setStartValue(QPoint(bus_x,bus_y));
                        bus_x-=distance-(bus_y-y_1-3); //这点是为了让图标对齐
                        bus_y=y_1;
                        anim->setKeyValueAt(0.5,QPoint(x_2,y_1));
                        anim->setEndValue(QPoint(bus_x,bus_y));
                        anim->start();
                    }
                }
            }
            output();
        }
    }

}

//析构函数
Widget::~Widget()
{
    delete ui;
}

//输出
void Widget::output(){
    static QString s;  //输出的字符串，将数组转化为字符串后输出在label中
    s="";
    head={"target:","clockwise:","counterclockwise:"};
    s+=QString("TIME:%1%2").arg(curtime).arg("\n");
    for(int i = 0; i < array.size(); i++)
    {
        s+=head[i];
        for (int  j= 1; j <= TOTAL_STATION;j++)
        {
            QString temp;
            temp.setNum(array[i][j]);
            s+=temp;
        }
        s+="\n";
    }
    ui->output_label->setText(s);

    QString b;
    b=QString::number(Bus.position);
    ui->pos->setText(b);
}

void Widget::ShortDirection(int aim)//默认只会在站点处调用,输入目标
{
    int cur=Bus.position/DISTANCE+1;
    int shun=0,ni=0;
    if(cur==aim)
        Bus.direction=0;
    else if(cur<aim)
    {
        shun=aim-cur;
        ni=TOTAL_STATION+cur-aim;
    }
    else if(cur>aim)
    {
        shun=TOTAL_STATION-cur+aim;
        ni=cur-aim;
    }
    if(shun>ni)
        Bus.direction=2;
    else if(shun<ni||(shun==ni&&shun!=0))
        Bus.direction=1;
}

